package com.soa.zuul.service;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.soa.zuul.entity.GatewayService;
import com.soa.zuul.entity.GatewayUser;
import com.soa.zuul.entity.GatewayUserHttpAuth;
import com.soa.zuul.entity.GatewayUserServiceAuth;
import com.soa.zuul.util.Json;





@Service
@Transactional
public class UserAuthService {
	public final static Logger logger = LoggerFactory.getLogger(UserAuthService.class);
	@PersistenceContext
	private EntityManager entityManager;
	@Resource
	StringRedisTemplate stringRedisTemplate;
	private Session session;

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public Session getSession() {
		return this.getEntityManager().unwrap(org.hibernate.Session.class);
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}
	
	/**
	 * 根据token查询用户信息
	 * @param access_token
	 * @return
	 */
	public GatewayUser getGatewayUserByToken(String access_token) {
		String rediskey = GatewayUser.class.getSimpleName() + ":token:" + access_token;
		String user = null;
		try {
			user = stringRedisTemplate.opsForValue().get(rediskey);
		} catch (Exception e) {
			user = null;
			logger.info("redsi读取异常:   " + e.getMessage());
			e.printStackTrace();
		}
		//申请token时候存入redis中的,如果网站在存入redis之后修改了。此时这里不是最新数据。
		GatewayUser gatewayUser = null;
		GatewayUser newgatewayUser = null;
		if (!StringUtils.isEmpty(user)) {
			gatewayUser = Json.GSON.fromJson(user,GatewayUser.class);
		}
		if(gatewayUser!=null){
			//取数据库最新同步的
			String newkey= GatewayUser.class.getSimpleName() + ":id:" + gatewayUser.getId();
			try {
				user = stringRedisTemplate.opsForValue().get(newkey);
			} catch (Exception e) {
				user = null;
				logger.info("redsi读取异常:   " + e.getMessage());
				e.printStackTrace();
			}
			
			if (!StringUtils.isEmpty(user)) {
				newgatewayUser = Json.GSON.fromJson(user,GatewayUser.class);
			}else{
				newgatewayUser=gatewayUser;
			}
		}
		return newgatewayUser;
	}

	/**
	 * 根据token和url查询用户执行权限
	 * @param url
	 * @param key
	 * @return
	 */
	public GatewayUserServiceAuth getUserServiceAuthByKey(String url, String key) {
		String rediskey = GatewayUserServiceAuth.class.getSimpleName() + ":" + key + ":" + url;
		String userAuth = null;
		try {
			userAuth = stringRedisTemplate.opsForValue().get(rediskey);
		} catch (Exception e) {
			userAuth = null;
			e.printStackTrace();
		}
		GatewayUserServiceAuth gatewayUserServiceAuth = null;
		if (!StringUtils.isEmpty(userAuth)) {
			gatewayUserServiceAuth = Json.GSON.fromJson(userAuth,GatewayUserServiceAuth.class);
		} else {// redis 里面没有，则去数据中查,查到了同步到redis里面
			Criteria authCriteria = this.getSession().createCriteria(GatewayUserServiceAuth.class);
			authCriteria.createAlias("gatewayService", "service");
			authCriteria.createAlias("gatewayUser", "user");
			authCriteria.add(Restrictions.eq("user.key", key));
			authCriteria.add(Restrictions.eq("service.path", url));
			gatewayUserServiceAuth = (GatewayUserServiceAuth) authCriteria.uniqueResult();
			if (gatewayUserServiceAuth != null) {
				try {
					stringRedisTemplate.opsForValue().set(rediskey,
							Json.GSON.toJson(gatewayUserServiceAuth));
				} catch (Exception e) {
					e.printStackTrace();
				}
				logger.info("成功同步gatewayUserServiceAuth到redsi:   " + rediskey);
			}
		}
		return gatewayUserServiceAuth;
	}
	
	
	/**
	 * 根据token和apiid查询应用执行权限
	 * @param apiid
	 * @param key
	 * @return
	 */
	public GatewayUserHttpAuth getUserApiAuthByKey(String apiid, String key) {
		String rediskey = GatewayUserHttpAuth.class.getSimpleName() + ":" + key + ":" + apiid;
		String userAuth = null;
		try {
			userAuth = stringRedisTemplate.opsForValue().get(rediskey);
		} catch (Exception e) {
			userAuth = null;
			e.printStackTrace();
		}
		GatewayUserHttpAuth gatewayUserHttpAuth = null;
		if (!StringUtils.isEmpty(userAuth)) {
			gatewayUserHttpAuth = Json.GSON.fromJson(userAuth,GatewayUserHttpAuth.class);
		} else {// redis 里面没有，则去数据中查,查到了同步到redis里面
			Criteria authCriteria = this.getSession().createCriteria(GatewayUserHttpAuth.class);
			authCriteria.createAlias("gatewayHttpApi", "api");
			authCriteria.createAlias("gatewayUser", "user");
			authCriteria.add(Restrictions.eq("user.key", key));
			authCriteria.add(Restrictions.eq("api.id", apiid));
			gatewayUserHttpAuth = (GatewayUserHttpAuth) authCriteria.uniqueResult();
			if (gatewayUserHttpAuth != null) {
				try {
					stringRedisTemplate.opsForValue().set(rediskey,
							Json.GSON.toJson(gatewayUserHttpAuth));
				} catch (Exception e) {
					e.printStackTrace();
				}
				logger.info("成功同步到redsi:   " + rediskey);
			}
		}
		return gatewayUserHttpAuth;
	}
}
